﻿using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Interactivity;
using AvaloniaEdit;
using AvaloniaEdit.CodeCompletion;
using AvaloniaEdit.TextMate;
using MarkdownRow.Assets;
using MarkdownRow.Edit;
using MarkdownRow.Edit.CompletionData;
using TextMateSharp.Grammars;

namespace MarkdownRow.EditView;

public abstract class Editor : UserControl
{
    protected Doc doc { get; set; } = new();
    protected TextEditor _editor;
    private OverloadInsightWindow? InsightWindow => null;
    private CompletionWindow? TextEditCompletionWindow => null;
    protected CompletionWindow? CompletionWindow { get; set; }
    private RegistryOptions RegistryOptions { get; set; }
    private TextMate.Installation TextMateInstallation { get; set; }
    public abstract void ContextChange(string s);
    public abstract void CopyMenuClick(object? sender, RoutedEventArgs e);
    public abstract void ShowTabs(object? sender, RoutedEventArgs e);
    public abstract void ShowSpaces(object? sender, RoutedEventArgs e);
    public abstract void ShowEOL(object? sender, RoutedEventArgs e);
    public abstract void SearchMenuClick(object? sender, RoutedEventArgs e);
    public abstract void PasteMenuClick(object? sender, RoutedEventArgs e);
    public abstract void CutMenuClick(object? sender, RoutedEventArgs e);
    public abstract string GetText();

    protected void Init(string context)   
    {
        _editor = this.FindControl<TextEditor>("Editor")!;
        _editor.TextArea.TextEntered += TextEntered;
        _editor.TextArea.TextEntering += TextEntering;
        RegistryOptions = new RegistryOptions(ThemeName.Monokai);
        TextMateInstallation = _editor.InstallTextMate(RegistryOptions);
        TextMateInstallation.SetGrammar(
            RegistryOptions.GetScopeByLanguageId(RegistryOptions.GetLanguageByExtension(".md").Id));
        _editor.TextArea.TextView.LineTransformers.Add(new ThroughTransformer());
        
        _editor.Text = context;
    }

    private void TextEntered(object? sender, TextInputEventArgs e)
    {
        if (string.IsNullOrEmpty(e.Text) || e.Text == "\n" || e.Text == " ")
            return;
        CompletionWindow = new CompletionWindow(_editor.TextArea);
        CompletionWindow.Closed += (_, _) => CompletionWindow = null;
        var data = CompletionWindow.CompletionList.CompletionData;
        foreach (var item in CompletionDataList.Trigger(e.Text!,doc))
            data.Add(item);
        CompletionWindow.Show();
    }

    private void TextEntering(object? sender, TextInputEventArgs e)
    {
        if (e.Text!.Length > 0 && TextEditCompletionWindow != null)
        {
            if (!char.IsLetterOrDigit(e.Text[0]))
            {
                //每当在完成窗口打开时键入非字母时，插入当前选定的元素。
                TextEditCompletionWindow.CompletionList.RequestInsertion(e);
            }
        }

        InsightWindow?.Hide();

        // 不要设置 e.Handled=true。我们仍然希望插入键入的字符。
    }
    
    protected MainWindow? GetMain()
    {
        var control = this as Control;
        while (true)
        {
            if (control == null) return null;
            if (control is MainWindow window) return window;
            control = control.Parent as Control;
        }
    }
}